home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_11_05
/
test_obj
/
dgen.syn
< prev
next >
Wrap
Text File
|
1993-01-20
|
8KB
|
236 lines
/* File: DGEN.SYN
Copyright Norman Wilde 1993
Notes: Contains Anagram syntax for a test driver generator that
handles input data for some of the basic types of C, that is:
char
string (ie. char * with nul termination)
int
double
FILE *
as well as for the objects in the Invoice example:
Item
Client
Invoice
Array inputs are tricky since the compiler generally needs
to know the dimension of the array to be able to interpret
an initializer. One way around this is to 'typedef' an array
of the desired size. As illustration, we include the following
type:
intarr2 (array of 2 ints - typedef as INTARR2)
Users will normally add to this list any other types or
object classes used in the code they plan to test. Just add
another alternative to the 'declaration' production below.
When AnaGram processes this file, it will produce a C program
called DGEN.C
that reads test specification files and writes test driver
programs. Compile DGEN.C and link with TUTILS.C to produce
DGEN.EXE.
See the README.TXT file for further explanations of the
testing system in general. See TUTILS.H for descriptions
of the functions used in the reduction procedures. See
T001.TST for an example of a test specification file
that is described by this grammar. See T001.CPP for an
example of a generated test driver created by running
DGEN.EXE.
*/
{
#include "tutils.h"
}
// AnaGram configuration parameter settings
[
~allow macros
]
// Basic syntax stuff
alpha = 'a-z' + 'A-Z' + '_'
digit = '0-9'
alphanumeric = alpha + digit
doubleQuote = '\"'
eof = -1 + 0 + ^D + ^Z
blank = ' ' + '\t'
eol = '\n'
stringCharacter = ~(eof + '"' + eol)
blockCharacter = ~(eof + '{' + '}')
commentCharacter = ~(eof + eol)
notCloseBracket = ~(']')
space
-> blank | eol | comment
comment
-> "//", commentCharacter?..., eol
(char *)variable
-> varStart, varRest? =release();
varStart
-> alpha:c =collectFirst(c);
varRest
-> alphanumeric:c =collect(c);
-> varRest, alphanumeric:c =collect(c);
(char*) string
-> doubleQuote, stringContents,
doubleQuote =release();
stringContents
-> stringCharacter:c =collectFirst(c);
-> stringContents,
stringCharacter:c =collect(c);
// The following is a simplified C
// language block, any '{' and '}'
// must balance, even in strings or
// comments
(char *) block
-> blockStart,
blockComponent?...,
'}' ={collect('}');return(release());}
blockStart
-> '{' =collectFirst('{');
blockComponent
-> blockCharacter:c =collect(c);
-> nestedBlock
nestedBlock
-> nestStart, blockComponent?...,
'}' =collect('}');
nestStart
-> '{' =collect('{');
(struct STRLIST *) initializerList
-> initializer:s =listNew(s,"");
-> initializerList:lst, initializer:s =listAdd(lst,s,"");
(char *) initializer
-> '[', initializer contents, ']',
space?... =release();
initializer contents
-> notCloseBracket:c =collectFirst(c);
-> initializer contents,
notCloseBracket:c =collect(c);
// GRAMMAR FOR A TEST SPECIFICATION FILE
grammar
-> space?..., statement..., eof =writeDriver();
statement
-> embeddedBlock, space?...
-> runStatement, space?...
-> declaration, space?...
// a block of C code to be copied into the generated test driver
embeddedBlock
-> block:eb =addBlock(eb);
// a runStatement describes a set of tests to be run. The driver
// main loop will choose one combination of the values of the
// variables in the variableList and will use that set of values
// to execute the block of c/c++ code. If the keyword in the
// testSpec is "combining", the main loop will generate all
// combinations of the possible values of the variables. If
// the keyword in the testSpec is "varying", each of the variables
// will be varied one by one, with the other variables held
// at their default value (ie, the first value in the declaration).
runStatement
-> runHeader, space..., testSpec
runHeader
-> "runtest", space..., string:n =setRunName(n);
testSpec
-> "varying", space...,
variableList:vl, block:b =makeVary(vl,b);
-> "combining", space...,
variableList:vl, block:b =makeComb(vl,b);
(struct STRLIST *) variableList
-> variable:v, space... =listNew(v,"");
-> variableList:lst, variable:v,
space... =listAdd(lst,v,"");
// Syntax for declarations of set variables. Each variable
// represents a set of objects; the members of the set
// are given by the initializers in the declaration.
declaration
-> charDeclaration
-> stringDeclaration
-> intDeclaration
-> doubleDeclaration
-> FILEDeclaration
-> intarr2Declaration
-> ItemDeclaration
-> ClientDeclaration
-> InvoiceDeclaration
// add others as needed
// Declaration of a set of chars
charDeclaration
-> "char", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"char","char",il);
// the initializers should be single
// characters, eg:
// ['A'] [ '\n' ] ['\0']
// Declaration of a set of strings
stringDeclaration
-> "string", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"char *","char *",il);
// the initializers should be single c
// strings, eg:
// ["now is"] [" the time" ] [""] [ "I think"]
// Declaration of a set of integers
intDeclaration
-> "int", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"int","int",il);
// the initializers should be single
// integers, eg:
// [12] [ 2 ] [18]
// Declaration of a set of doubles
doubleDeclaration
-> "double", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"double","double&",il);
// the initializers should be single
// floating point numbers, eg:
// [1.1] [ -2.0 ]
// Declaration of a set of FILE pointers
FILEDeclaration
-> "FILE", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"FILE *","FILE *",il);
// the initializers should be statements that return a FILE * eg:
// [ fopen("fname", "r") ]
// Declaration of a set of arrays
// of 2 integers (must include
// "typedef int INTARR2 []"
// in test specification.
intarr2Declaration
-> "intarr2", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"INTARR2","INTARR2",il);
// the initializers should each be a list of
// integers in braces, eg:
// [ { 1, 3} ]
// Declaration of a set of Item objects
ItemDeclaration
-> "Item", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"Item","Item&",il);
// the initializers should be constructors of Item objects, eg:
// [ Item(1001, 2, 12.38) ]
// Declaration of a set of Client objects
ClientDeclaration
-> "Client", space...,
variableList:vl, "{", space?...,
initializerList:il, "}" =addTVars(vl,"Client","Client&",il);
// the initializers should be constructors of Client objects, eg:
// [ Client(RETAIL) ]
// Declaration of a set of Invoice objects
InvoiceDeclaration
-> "Invoice", space...,
variableList:vl,